﻿using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Threading;
using System.Xml;
using System.Windows.Forms;

namespace PublicTransport
{
    abstract class GpsMapImage
    {
        protected Image image_;
        protected int mapType = 0;
        public Image image
        {
            get
            {
                newImage = false;
                return image_;
            }
            set
            {
                image_ = value;
                newImage = true;
            }
        }
        public bool newImage = false;
        public bool ok = false;
        public bool finished = false;
        public string error;
        protected int zoom_;
        protected int zoom
        {
            get
            {
                return zoom_;
            }
            set
            {
                zoom_ = value;
                resolution = 2.0 * Math.PI * 6378137.0 / 256.0 / Math.Pow(2, zoom);
            }
        }
        protected double resolution;
        protected double originShift = 2.0 * Math.PI * 6378137 / 2.0;
        protected Point upperLeftPixels;
        protected int sizeY;
        protected int sizeX;
        public string xmlRequest;
        protected GpsPoint centerPoint;
        protected bool httpBlock = false;
        protected bool constructorFinished = false;

        public GpsMapImage()
        {
        }

        public abstract void getImage();

        public void changeMapType()
        {
            if (mapType == 0)
            {
                mapType = 1;
            }
            else
            {
                mapType = 0;
            }
            getImage();
        }

        public void changeZoom(bool larger)
        {
            zoom += (larger ? 1 : -1);
            if (zoom > 22) zoom = 22;
            if (zoom < 0) zoom = 0;
            getImage();
        }

        public void changeCenter(int change) //direction 0 = east, 1 = north, 2 = west, 3 = south
        {
            Point tmpPoint = degreesToPixels(centerPoint);
            tmpPoint.Y += (int)Math.Round(change == 3 ? sizeY * -0.2 : (change == 1 ? sizeY * 0.2 : 0));
            tmpPoint.X += (int)Math.Round(change == 2 ? sizeX * -0.2 : (change == 0 ? sizeX * 0.2 : 0));
            centerPoint = pixelsToDegrees(tmpPoint);
            getImage();
        }

        public GpsPoint pixelsToDegrees(Point pixels)
        {
            return new GpsPoint(180.0 / Math.PI * (2.0 * Math.Atan(Math.Exp(((((double)pixels.Y * resolution - originShift) / originShift) * 180.0) * Math.PI / 180.0)) - Math.PI / 2.0), (((double)pixels.X * resolution - originShift) / originShift) * 180.0);
        }

        protected Point degreesToPixels(GpsPoint gpsPoint)
        {
            return new Point((int)Math.Round(((gpsPoint.X * originShift / 180.0) + originShift) / resolution), (int)Math.Round((((Math.Log(Math.Tan((90.0 + gpsPoint.Y) * Math.PI / 360.0)) / (Math.PI / 180.0)) * originShift / 180.0) + originShift) / resolution));
        }

        public Point degreesToPixelsFromUpperLeft(GpsPoint gpsPoint)
        {
            Point point = degreesToPixels(gpsPoint);
            return new Point(point.X - upperLeftPixels.X, sizeY - (point.Y - upperLeftPixels.Y));
        }
    }
}
